package template

import (
	"bytes"
	"context"
	"encoding/json"
	"gitee.com/hbjava_021/go-common/logger"
	"gitee.com/hbjava_021/go-common/util"
	"gitee.com/hbjava_021/go-elasticsearch-api/domain"
	"github.com/elastic/go-elasticsearch/v7"
	"io/ioutil"
	"log"
	"strings"
)

type Client struct {
	Config elasticsearch.Config
}
type Api struct {
	client *elasticsearch.Client
}

func (c *Client) Connect() Api {
	es, err := elasticsearch.NewClient(c.Config)
	if err != nil {
		log.Fatalf("Error creating the client: %s", err)
	}
	return Api{client: es}
}

func (api Api) Search(index string, body interface{}) domain.ResultHits {
	var buf bytes.Buffer
	byte, err := json.Marshal(body)
	buf.Write(byte)
	// 执行搜索请求.
	res, err := api.client.Search(
		api.client.Search.WithContext(context.Background()),
		api.client.Search.WithIndex(index),
		api.client.Search.WithBody(&buf),
		api.client.Search.WithTrackTotalHits(true),
		api.client.Search.WithPretty(),
	)
	if err != nil {
		logger.Error.Printf("搜索异常: %s\n", err)
	}
	resultHits := domain.ResultHits{}
	bt, err := ioutil.ReadAll(res.Body)
	if err != nil {
		logger.Error.Printf("读取搜索结果异常: %s\n: %s", err)
	}
	json.Unmarshal(bt, &resultHits)
	return resultHits
}
func (api Api) UpdateByQuery(index string, body interface{}) {
	var buf bytes.Buffer
	byte, err := json.Marshal(body)
	buf.Write(byte)
	// 执行搜索请求.
	res, err := api.client.UpdateByQuery(
		[]string{index},
		api.client.UpdateByQuery.WithContext(context.Background()),
		api.client.UpdateByQuery.WithBody(&buf),
		api.client.UpdateByQuery.WithPretty(),
	)
	resStr, err := ioutil.ReadAll(res.Body)
	if err != nil {
		logger.Error.Printf("UpdateByQuery异常: %s\n", err)
	}
	logger.Info.Printf("更新结果:%s\n", resStr)
}
func (api Api) Update(index string, id string, body interface{}) {
	var buf bytes.Buffer
	byte, err := json.Marshal(body)
	buf.Write(byte)
	// 执行搜索请求.
	res, err := api.client.Update(
		index,
		id,
		&buf,
		api.client.Update.WithContext(context.Background()),
		api.client.Update.WithPretty(),
	)
	resStr, err := ioutil.ReadAll(res.Body)
	if err != nil {
		logger.Error.Printf("Update异常: %s\n", err)
	}
	logger.Info.Printf("更新结果:%s\n", resStr)
}

/**
{ "update": {"_id": "5", "_index": "index1"} }
{ "doc": {"my_field": "baz"} }
{ "update": {"_id": "6", "_index": "index1"} }
{ "doc": {"my_field": "baz"} }
{ "update": {"_id": "7", "_index": "index1"} }
{ "doc": {"my_field": "baz"} }
*/
func (api Api) ExecuteBulk(bulk domain.Bulk) {
	builder := strings.Builder{}
	for _, item := range bulk.BulkItems {
		builder.WriteString("\n")
		builder.WriteString(util.ToJsonString(item.Update))
		builder.WriteString("\n")
		builder.WriteString(util.ToJsonString(item.Doc))
		builder.WriteString("\n")
	}
	logger.Info.Printf(builder.String())
	res, err := api.client.Bulk(
		strings.NewReader(builder.String()),
	)
	resStr, err := ioutil.ReadAll(res.Body)
	if err != nil {
		logger.Error.Printf("批量执行异常: %s\n", err)
	}
	logger.Info.Printf("批量执行结果:%s\n", resStr)
}
